package com.ilink.teacherservice.service.Screen;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ilink.ilinkapi.client.DataAnalysisClient;
import com.ilink.ilinkcommon.domain.PO.studyservice.*;
import com.ilink.ilinkcommon.domain.R;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;

import com.ilink.teacherservice.mapper.CourseSourceMapper;
import com.ilink.teacherservice.mapper.Screen.DataScreenMapper;
import com.ilink.teacherservice.mapper.StudyCourseFileMapper;
import com.ilink.teacherservice.mapper.StudyTeacherCourseMapper;
import com.ilink.teacherservice.mapper.UserCourseStudyRecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDate;
import java.sql.Date;
import java.util.*;

@Service
public class ScreenDataInsert {

    @Autowired
    private DataScreenMapper dataScreenMapper; // 第一张图片对应的表 Mapper

    @Autowired
    private CourseSourceMapper courseSourceMapper; // 第二张图片对应的表 Mapper

    @Autowired
    private StudyCourseFileMapper courseFileMapper; // 第三张图片对应的表 Mapper

    @Autowired
    private StudyTeacherCourseMapper studyTeacherCourseMapper; // 第四张图片对应的表 Mapper

    @Autowired
    private UserCourseStudyRecordMapper userCourseStudyRecordMapper; // 第五张图片对应的表 Mapper

    @Autowired
    private DataAnalysisClient dataAnalysisClient; // 跨服务接口客户端


    private static final Logger logger = LoggerFactory.getLogger(ScreenDataInsert.class);

    @Scheduled(cron = "0 0 0 * * ?") // 每天午夜0点执行
    public void insertCourseData() {

        // 获取当前日期，不包含时间部分
        LocalDate currentDate = LocalDate.now();

        // 将当前日期减去一天，获取前一天的日期
        currentDate = currentDate.minusDays(1);

        // 将 LocalDate 转换为 java.sql.Date（用于数据库查询）
        Date sqlDate = Date.valueOf(currentDate);

        logger.info("开始执行 insertCourseData 任务，处理日期：{}", sqlDate);

        // Step 1: 按照 coursesource_id 分组进行聚合
        List<UserCourseStudyRecord> studyRecords = userCourseStudyRecordMapper.selectList(null);

        // 按 coursesource_id 分组并计算每个组的 study_duration 总和和不同 user_id 的数量
        Map<Long, Integer> studyDurationMap = new HashMap<>();
        Map<Long, Set<String>> userIdSetMap = new HashMap<>();

        for (UserCourseStudyRecord studyRecord : studyRecords) {
            Long courseSourceId = studyRecord.getCoursesourceId();
            Integer studyDuration = studyRecord.getStudyDuration();
            String userId = studyRecord.getUserId();

            // 累加 study_duration
            studyDurationMap.put(courseSourceId, studyDurationMap.getOrDefault(courseSourceId, 0) + studyDuration);

            // 统计不同 user_id
            userIdSetMap.computeIfAbsent(courseSourceId, k -> new HashSet<>()).add(userId);
        }

        // 遍历聚合结果并插入数据到第一张表
        for (Long courseSourceId : studyDurationMap.keySet()) {
            // 检查 tb_screen 表中是否已经存在相同的 coursesource_id 和当前日期的组合
            TeacherScreen existingRecord = dataScreenMapper.selectOne(
                    new QueryWrapper<TeacherScreen>()
                            .eq("coursesource_id", courseSourceId)
                            .eq("time", sqlDate)
            );
            if (existingRecord != null) {
                logger.info("Record with coursesource_id {} and date {} already exists. Skipping.", courseSourceId, sqlDate);
                continue;  // 如果已存在，跳过该记录
            }

            // 获取总的 study_duration 和 unique user_id 数量
            Integer totalStudyDuration = studyDurationMap.get(courseSourceId);
            Integer studentNum = userIdSetMap.get(courseSourceId).size();

            // 创建新记录并插入
            TeacherScreen newRecord = new TeacherScreen();
            newRecord.setCoursesourceId(courseSourceId);
            newRecord.setCourseId(0L);
            newRecord.setTeacherId("0");
            newRecord.setFileId(0L);
            newRecord.setChapterId(0L);
            newRecord.setStudyNum(0); // 设置默认值为 0
            newRecord.setStudyDurationHistory(totalStudyDuration); // 设置聚合的 study_duration 总和
            newRecord.setStudentNum(studentNum); // 设置不同 user_id 数量
            newRecord.setStudentNumHistory(0); // 设置为 0

            // 查找最近日期的相同 coursesource_id 记录
            TeacherScreen latestRecord = dataScreenMapper.selectOne(
                    new QueryWrapper<TeacherScreen>()
                            .eq("coursesource_id", courseSourceId)
                            .lt("time", sqlDate)
                            .orderByDesc("time")
                            .last("LIMIT 1")
            );

            if (latestRecord == null) {
                // 首次出现，StudyDuration 设为 totalStudyDuration
                newRecord.setStudyDuration(totalStudyDuration);
            } else {
                // 不是首次出现，计算 StudyDuration 为当前的 studyDurationHistory 减去最近记录的 studyDurationHistory
                int previousStudyDurationHistory = latestRecord.getStudyDurationHistory();
                int calculatedStudyDuration = totalStudyDuration - previousStudyDurationHistory;
                newRecord.setStudyDuration(calculatedStudyDuration);
            }
            // 设置日期为前一天的日期
            newRecord.setTime(sqlDate);

            dataScreenMapper.insert(newRecord);
        }

        // Step 2: 遍历第一张表，用 courseSourceId 去第二张表匹配，填入 course_id 和 file_id
        List<TeacherScreen> teacherScreens = dataScreenMapper.selectList(
                new QueryWrapper<TeacherScreen>().eq("time", sqlDate)
        );
        for (TeacherScreen teacherScreen : teacherScreens) {
            Long courseSourceId = teacherScreen.getCoursesourceId();
            CourseSource courseSource = courseSourceMapper.selectOne(
                    new QueryWrapper<CourseSource>().eq("coursesource_id", courseSourceId)
            );
            if (courseSource != null) {
                teacherScreen.setCourseId(courseSource.getCourseId());
                teacherScreen.setFileId(courseSource.getFileId());

                // 使用 QueryWrapper 检查联合主键条件并更新
                dataScreenMapper.update(teacherScreen,
                        new QueryWrapper<TeacherScreen>()
                                .eq("coursesource_id", teacherScreen.getCoursesourceId())
                                .eq("time", teacherScreen.getTime())
                );
            }
        }

        // Step 3: 用第一张表的 file_id 去第三张表匹配，填入 chapter_id
        for (TeacherScreen teacherScreen : teacherScreens) {
            Long fileId = teacherScreen.getFileId();
            StudyCourseFile courseFile = courseFileMapper.selectOne(
                    new QueryWrapper<StudyCourseFile>().eq("courseFile_id", fileId)
            );
            if (courseFile != null) {
                teacherScreen.setChapterId(courseFile.getParentId());

                // 使用 QueryWrapper 检查联合主键条件并更新
                dataScreenMapper.update(teacherScreen,
                        new QueryWrapper<TeacherScreen>()
                                .eq("coursesource_id", teacherScreen.getCoursesourceId())
                                .eq("time", teacherScreen.getTime())
                );
            }
        }

        // Step 4: 用第一张表的 course_id 去第四张表匹配，填入 teacher_id
        for (TeacherScreen teacherScreen : teacherScreens) {
            Long courseId = teacherScreen.getCourseId();
            StudyTeacherCourse teacherRecord = studyTeacherCourseMapper.selectOne(
                    new QueryWrapper<StudyTeacherCourse>().eq("course_id", courseId)
            );
            if (teacherRecord != null) {
                teacherScreen.setTeacherId(teacherRecord.getTeacherId());

                // 使用 QueryWrapper 检查联合主键条件并更新
                dataScreenMapper.update(teacherScreen,
                        new QueryWrapper<TeacherScreen>()
                                .eq("coursesource_id", teacherScreen.getCoursesourceId())
                                .eq("time", teacherScreen.getTime())
                );
            }
        }

// Step 5: 更新 study_num 字段
        logger.info("开始更新 study_num 字段...");
        R response = dataAnalysisClient.getCourseSourceAccessInfo();
        if (response == null) {
            logger.error("接口返回为空，无法处理");
            return;
        }

// 使用 HttpStatus 判断状态码是否成功
        HttpStatus httpStatus = HttpStatus.valueOf(response.getCode());
        if (!httpStatus.is2xxSuccessful()) {
            logger.error("获取回放课程时，获取用户元数据失败，状态码：{}，错误信息：{}", response.getCode(), response.getMsg());
            return;
        }

// 使用 ObjectMapper 解析 data 数据
        ObjectMapper objectMapper = new ObjectMapper();
        List<Map<String, Object>> dataList;
        try {
            String dataJson = objectMapper.writeValueAsString(response.getData());
            dataList = objectMapper.readValue(dataJson, new TypeReference<List<Map<String, Object>>>() {});
        } catch (Exception e) {
            logger.error("解析接口返回数据失败：{}", e.getMessage(), e);
            return;
        }

// 按日期逐条处理 accessInfo
        for (Map<String, Object> dayData : dataList) {
            String dateStr = (String) dayData.get("date");
            Date specificDate;
            try {
                specificDate = Date.valueOf(dateStr); // 将日期字符串转为 java.sql.Date
            } catch (IllegalArgumentException e) {
                logger.error("日期格式不正确：{}", dateStr);
                continue;
            }

            List<Map<String, Object>> accessInfo = (List<Map<String, Object>>) dayData.get("accessInfo");
            if (accessInfo == null || accessInfo.isEmpty()) {
                logger.warn("日期 {} 没有 accessInfo 数据，跳过更新", specificDate);
                continue;
            }

            // 按日期匹配数据库中的记录并更新 study_num
            for (Map<String, Object> info : accessInfo) {
                Long courseSourceId = Long.valueOf(info.get("courseSourceId").toString());
                Integer count = Integer.valueOf(info.get("count").toString());

                // 查询对应日期和课程源 ID 的记录
                TeacherScreen teacherScreen = dataScreenMapper.selectOne(
                        new QueryWrapper<TeacherScreen>()
                                .eq("coursesource_id", courseSourceId)
                                .eq("time", specificDate)
                );
                if (teacherScreen == null) {
                    logger.warn("未找到 coursesource_id {} 和日期 {} 对应的记录，跳过更新", courseSourceId, specificDate);
                    continue;
                }

                // 更新 study_num 字段
                teacherScreen.setStudyNum(count);
                dataScreenMapper.update(teacherScreen,
                        new QueryWrapper<TeacherScreen>()
                                .eq("coursesource_id", teacherScreen.getCoursesourceId())
                                .eq("time", teacherScreen.getTime())
                );
                logger.info("更新 study_num 字段，coursesource_id: {}, time: {}, study_num: {}",
                        teacherScreen.getCoursesourceId(), teacherScreen.getTime(), count);
            }
        }
        logger.info("insertCourseData task completed for date {}", sqlDate);
    }
}
